﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Quizz.Infrastructure;
using Quizz.Library.Common;
using Quizz.Library.QuizzServiceReference;
using Quizz.Infrastructure.Models;
using Quizz.Library.Helper;
using Quizz.Infrastructure.Util;
using Quizz.Infrastructure.DataTypes;
using System.Web;


namespace Quizz.Library.Actions
{
    public class QuestionAction : BasicAction
    {
        #region Fields

        #endregion

        #region Public methods

        public QuestionAction(System.Web.Mvc.Controller controller)
            : base(controller) { }

        public JsonResult Add(Question question)
        {
            var validateResult = ValidateQuestion(question);
            if (validateResult.HasError())
            {
                return CommonMethods.CreateJson(new { result = false, message = validateResult.ToString("<br />") }, false);
            }
            question.CreatedDate = DateTime.Now;
            question.CreatorId = AccessFactory.CurrentUser.Id;
            question.Modified = DateTime.Now;
            question.Sumary = question.Content.Substring(0, Math.Min(50, question.Content.Length));

            using (var proxy = new QuizzProjectServiceClient())
            {
                try
                {
                    proxy.QuestionInsert(question);
                    return CommonMethods.CreateJson(new { result = true }, false);
                }
                catch(Exception ex)
                {
                    return CommonMethods.CreateJson(new { result = false, message = ex.ToString() }, false);
                }
            }
        }

        public JsonResult GetPage(long subjectId, int page, int count, string orderCol)
        {
            using (var proxy = new QuizzProjectServiceClient())
            {
                var items = proxy.QuestionGetPage(AccessFactory.CurrentUser.Id, subjectId, page, count, orderCol);
                var subjects = proxy.SubjectGetAll().ToDictionary(k => k.Id);
                var pageCount = (int)Math.Ceiling((double)items.ItemCount / count);
                return CommonMethods.CreateJson(new { result = true, data = BuildQuestionTable(items.Questions, subjects), itemCount = items.ItemCount, paging = BuildPagination(pageCount, page) }, false);
            }
        }

        public JsonResult View(long id)
        {
            using (var proxy = new QuizzProjectServiceClient())
            {
                var question = proxy.QuestionGetById(id);
                if (question == null) // Item does not exist
                {
                    return CommonMethods.CreateJson(new { result = false, message = "Dữ liệu không tồn tại." }, true);
                }
                var subjects = proxy.SubjectGetAll();
                ViewData["subjects"] = subjects;
                var result = question.Type == (int)QuestionType.MultiChose ?
                            RenderPartial("../UserControls/CreateMultiChoiseQuestion", question)
                            : RenderPartial("../UserControls/CreateMultiSubQuestion", question);

                return CommonMethods.CreateJson(new { result = true, data = result }, true);
            }
        }

        #endregion

        #region Private methods

        private string BuildQuestionTable(IList<Question> questions, IDictionary<long, Subject> subjects)
        {
            if (questions == null || questions.Count == 0)
            {
                return string.Empty;
            }

            var builder = new StringBuilder();
            const int count = 1;
            foreach (var item in questions)
            {
                builder.Append("<tr>");
                builder.AppendFormat("<td>{0}</td>", count);
                builder.AppendFormat("<td>{0}</td>", subjects[item.SubjectId.Value].Name);
                builder.AppendFormat("<td>{0}</td>", item.Sumary);
                builder.AppendFormat("<td>{0}</td>", Utilities.QuestionTypeToString(item.Type));
                builder.AppendFormat("<td>{0}</td>", Utilities.ShareTypeToString(item.ShareType));
                builder.AppendFormat("<td>{0}</td>", item.CreatedDate.ToString("dd/MM/yyyy HH:mm:ss"));
                builder.AppendFormat("<td>{0}</td>", item.Note);

                builder.AppendFormat(@"<td>
                            <a class='inline-button' onclick='ViewQuestion({0});' href='javascript:void(0)'><img alt='Sửa' src='/images/edit.png' /></a>
                            <a class='inline-button' onclick='ShowConfirmDelete({0});' href='javascript:void(0)'><img alt='Xóa' src='/images/delete2.png' /></a>
                        </td>", item.Id);

                builder.Append("</tr>");
            }

            return builder.ToString();
        }

        private ErrorReportResult ValidateQuestion(Question question)
        {
            var result = new ErrorReportResult();
            if (string.IsNullOrWhiteSpace(question.Content))
            {
                result.AddError("Nội dung câu hỏi không được trống");
            }
            if (question.Answers == null || question.Answers.Count < 2)
            {
                result.AddError("Câu hỏi phải có ít nhất 2 đáp án.");
            }
            else
            {
                if (!question.Answers.Any(a => a.IsTrue) || question.Answers.Where(a => a.IsTrue).Count() > 1)
                {
                    result.AddError("Câu hỏi phải có 1 đáp án đúng.");
                }
                if (question.Answers.Any(a => string.IsNullOrWhiteSpace(a.Content)))
                {
                    result.AddError("Nội dung câu trả lời không được bỏ trống.");
                }
            }
            return result;
        }

        private string BuildPagination(int page, int current)
        {
            if (page <= 1)
                return string.Empty;
            var result = new StringBuilder();

            if (current == 0)
            {
                result.Append("<span class=\"disable\">&lt;&lt;</span>");
            }
            else
            {
                result.Append("<a class=\"prev\" href=\"javascript:void(0)\" onclick=\"GetQuestionPage(_currentPage-1,_subjectId, _itemPerPage, _currentOrderCol);\">&lt;&lt;</a>");
            }

            var from = Math.Max(0, current - 5);
            var to = Math.Min(page - 1, current + 5);

            if (from != 0)
            {
                result.Append("<span class=\"pos\">...</span>");
            }

            for (var i = from; i <= to; i++)
            {
                if (current == i)
                {
                    result.AppendFormat("<span class=\"current\">{0}</span>", i + 1);
                }
                else
                {
                    result.AppendFormat("<a href=\"javascript:void(0)\" onclick=\"GetQuestionPage({0},_subjectId, _itemPerPage, _currentOrderCol);\">{1}</a>", i, i + 1);
                }
            }

            if (to < page - 1)
            {
                result.Append("<span class=\"pos\">...</span>");
            }

            if (current == page - 1)
            {
                result.Append("<span class=\"disable\">&gt;&gt;</span>");
            }
            else
            {
                result.Append("<a class=\"prev\" href=\"javascript:void(0)\"GetQuestionPage(_currentPage+1,_subjectId, _itemPerPage, _currentOrderCol);\">&gt;&gt;</a>");
            }

            return result.ToString();
        }
        #endregion

        public JsonResult Get(long id)
        {
            using (var proxy = new QuizzProjectServiceClient()){
                var question = proxy.QuestionGetById(id);
                if (question == null)
                    return CommonMethods.CreateJson(new { result = false, message = "Dữ liệu không tồn tại." }, false);
                return CommonMethods.CreateJson(new { result = true, data = question }, false);
            }
        }

        public JsonResult Delete(long id)
        {
            using (var proxy = new QuizzProjectServiceClient())
            {
                if (proxy.QuestionDelete(id))
                {
                    return CommonMethods.CreateJson(new { result = true }, false);
                }
                else
                {
                    return CommonMethods.CreateJson(new { result = false, message = "Không thể xóa câu hỏi này."}, false);
                }
            }
        }

        public JsonResult Create(int type)
        {
            if (type == (int)QuestionType.MultiChose)
            {
                using (var proxy = new QuizzProjectServiceClient())
                {
                    var subjects = proxy.SubjectGetAll();
                    var question = new Question
                    {
                        Type = type,
                        Content = "Nhập nội dung",
                        CreatedDate = DateTime.Now,
                        CreatorId = AccessFactory.CurrentUser.Id,
                        SubjectId = -1,
                        ShareType = (int)ShareType.Private
                    };
                    if (question.Answers == null)
                    {
                        question.Answers = new List<Answer>();
                    }
                    question.Answers.Add(new Answer
                                             {
                                                 Content = "Đáp án 1",
                                                 IsTrue = true
                                             });
                    question.Answers.Add(new Answer
                                             {
                                                 Content = "Đáp án 2",
                                                 IsTrue = false,
                                             });

                    ViewData["subjects"] = subjects;

                    return CommonMethods.CreateJson(new { result = true, data = RenderPartial("../UserControls/CreateMultiChoiseQuestion", question) }, false);
                }
            }
            else if (type == (int)QuestionType.MultiSubQuestion)
            {
                return null;
            }
            else
            {
                return CommonMethods.CreateJson(new { result = false, message = "Loại câu hỏi chưa được hỗ trợ." }, false);
            }
        }

        public JsonResult Update(Question question)
        {
            var validateResult = ValidateQuestion(question);
            if (validateResult.HasError())
            {
                return CommonMethods.CreateJson(new { result = false, message = validateResult.ToString("<br />") }, false);
            }

            using (var proxy = new QuizzProjectServiceClient())
            {
                try
                {
                    var original = proxy.QuestionGetById(question.Id);
                    if (original == null)
                        return CommonMethods.CreateJson(new {result = false, message = "Câu hỏi hiện không tồn tại."});

                    original.Answers.Clear();
                    original.Answers.AddRange(question.Answers);
                    original.Modified = DateTime.Now;
                    original.Sumary = question.Content.Substring(0, Math.Min(50, question.Content.Length));
                    original.SubjectId = question.SubjectId;
                    original.Note = question.Note;
                    original.Level = question.Level;
                    original.ShareType = question.ShareType;

                    proxy.QuestionUpdate(original);
                    return CommonMethods.CreateJson(new { result = true }, false);
                }
                catch (Exception ex)
                {
                    return CommonMethods.CreateJson(new { result = false, message = ex.ToString() }, false);
                }
            }
        }
    }
}
